libcurl URL API

URL API

libcurl은 URL을 구문 분석, 업데이트 및 생성하기 위한 API를 제공합니다. 이를 사용하여 응용 프로그램은 자체 목적을 위해 libcurl의 URL 파서를 사용할 수 있습니다. 동일한 파서를 사용함으로써 다른 해석으로 인한 보안 문제를 피할 수 있습니다.

Include files

URL API를 사용하려는 경우 코드에 <curl/curl.h>를 포함합니다.

1
2
3
4
#include <curl/curl.h>

CURLU *h = curl_url();
rc = curl_url_set(h, CURLUPART_URL, "ftp://example.com/no/where", 0);

Create, cleanup, duplicate

이 API를 사용하는 첫 번째 단계는 URL 정보와 리소스를 보유하는 CURLU * 핸들을 만드는 것입니다. 핸들은 단일 URL 및 모든 다른 구성 요소에 대한 정보를 보유하는 연결된 데이터 개체에 대한 참조입니다.

API를 사용하면 각 URL 구성 요소를 개별적으로 또는 전체 URL로 설정하거나 가져올 수 있습니다.

다음과 같이 URL 핸들을 만듭니다.

1
CURLU *h = curl_url();

완료되면 정리하십시오.

1
curl_url_cleanup(h);

핸들 사본이 필요하면 복사하십시오.

1
CURLU *nh = curl_url_dup(h);

Parse a URL

핸들에서 CURLUPART_URL 부분을 설정하여 전체 URL을 구문 분석합니다.

1
2
3
CURLU *h = curl_url();
rc = curl_url_set(h, CURLUPART_URL,
"https://example.com:449/foo/bar?name=moo", 0);

성공하면 rc에 CURLUE_OK가 포함되고 다른 URL 구성 요소가 핸들에 유지됩니다. libcurl에 관한 한 URL이 유효했음을 의미합니다.

함수 호출의 네 번째 인수는 특정 기능을 변경하기 위한 비트마스크입니다. 파서의 동작을 변경하기 위해 비트를 하나만 더 설정할 수 있습니다.

CURLU_NON_SUPPORT_SCHEME

curl_url_set()이 지원되지 않는 체계를 허용하도록 합니다. 설정하지 않으면 libcurl이 알고 있고 지원하는 내장 프로토콜에 대한 유일한 구성표가 허용됩니다.

CURLU_URLENCODE

공백 또는 “제어 문자”와 같은 이점이 있는 바이트가 있는 경우 함수 URL이 경로 부분을 인코딩하도록 합니다.

CURLU_DEFAULT_SCHEME

전달된 문자열이 체계를 사용하지 않는 경우 기본 체계를 의도한 것으로 가정합니다. 기본 체계는 HTTPS입니다. 이것이 설정되지 않으면 스킴 부분이 없는 URL은 유효한 것으로 승인되지 않습니다. 둘 다 설정된 경우 CURLU_GUESS_SCHEME 옵션을 재정의합니다.

CURLU_GUESS_SCHEME

libcurl이 URL이 스키마 없이 설정되도록 하고 대신 호스트 이름을 기반으로 의도한 스키마를 “추측”합니다. 가장 바깥쪽 하위 도메인 이름이 DICT, FTP, IMAP, LDAP, POP3 또는 SMTP와 일치하면 해당 체계가 사용되며, 그렇지 않으면 HTTP를 선택합니다. 둘 다 설정된 경우 우선적으로 적용되는 CURLU_DEFAULT_SCHEME 옵션과 충돌합니다.

CURLU_NO_AUTHORITY

권한 검사를 건너뜁니다. RFC는 개별 체계가 호스트 부분(일반적으로 권한의 유일한 필수 부분)을 생략하도록 허용하지만 libcurl은 이것이 사용자 지정 체계에 허용되는지 여부를 알 수 없습니다. 플래그를 지정하면 파일 구성표가 처리되는 방식과 유사한 빈 권한 섹션이 허용됩니다. CURLU_NON_SUPPORT_SCHEME와 조합해서만 사용할 수 있습니다.

CURLU_PATH_AS_IS

libcurl이 경로의 정규화를 건너뛰게 합니다. 이것은 curl이 점-슬래시 및 점-점 등의 시퀀스를 제거하는 절차입니다. 전송에 사용되는 동일한 옵션을 CURLOPT_PATH_AS_IS라고 합니다.

CURLU_ALLOW_SPACE

URL 파서가 가능한 경우 공간(ASCII 32)을 허용하도록 합니다. URL 구문은 일반적으로 공백을 허용하지 않지만 %20 또는 +로 인코딩해야 합니다. 공백이 허용되면 스키마에서 여전히 허용되지 않습니다. URL에서 공간이 사용되고 허용되면 CURLU_URLENCODE도 설정되지 않는 한 그대로 저장됩니다. 그러면 libcurl이 저장하기 전에 공간을 URL로 인코딩합니다. 이는 전체 URL 또는 개별 부분을 추출하기 위해 curl_url_get()을 사용할 때 URL이 구성되는 방식에 영향을 줍니다.

상대 URL로 리디렉션

핸들이 이미 URL을 구문 분석한 경우 두 번째 상대 URL을 설정하면 이에 맞게 “리디렉션”됩니다.

예를 들어, 먼저 원래 URL을 설정한 다음 “리디렉션”할 URL을 다음으로 설정합니다.

1
2
3
4
5
CURLU *h = curl_url();
rc = curl_url_set(h, CURLUPART_URL,
"https://example.com/foo/bar?name=moo", 0);

rc = curl_url_set(h, CURLUPART_URL, "../test?another", 0);

Get a URL

CURLU * 핸들은 URL 또는 URL의 일부를 나타내며 언제든지 해당 URL을 쉽게 추출할 수 있습니다.

1
2
3
char *url;
rc = curl_url_get(h, CURLUPART_URL, &url, CURLU_NO_DEFAULT_PORT);
curl_free(url);

핸들에 전체 URL을 추가하기에 충분한 정보가 없으면 오류를 반환합니다.
반환된 문자열은 작업을 마친 후 curl_free()로 해제해야 합니다.
함수 호출의 네 번째 인수에서 0은 특정 기능을 변경하기 위한 플래그 비트마스크입니다.

CURLU_DEFAULT_PORT

URL 핸들에 저장된 포트 번호가 없는 경우 이 옵션은 curl_url_get()이 사용된 체계에 대한 기본 포트를 반환하도록 합니다.

CURLU_DEFAULT_SCHEME

핸들에 저장된 체계가 없는 경우 이 옵션은 curl_url_get()이 오류 대신 기본 체계를 반환하도록 합니다.

CURLU_NO_DEFAULT_PORT

포트 번호가 스키마에 사용된 기본 포트와 일치하는 경우 생성된 URL에서 포트 번호를 사용하지 않도록 curl_url_get()에 지시합니다. 예를 들어 포트 번호 443이 설정되고 스키마가 https인 경우 추출된 URL에는 포트 번호가 포함되지 않습니다.

CURLU_URLENCODE

설정하면 전체 URL이 검색될 때 curl_url_get() URL이 호스트 이름 부분을 인코딩하도록 합니다. 설정되지 않은 경우(기본값) libcurl은 IDN 이름이 있는 그대로 표시되도록 지원하기 위해 호스트 이름이 “raw”인 URL을 반환합니다. IDN 호스트 이름은 일반적으로 비ASCII 바이트를 사용하며 그렇지 않으면 백분율로 인코딩됩니다.

URL 인코딩을 요청하지 않는 경우에도 %(바이트 37)는 호스트 이름이 유효한지 확인하기 위해 호스트 이름에서 URL로 인코딩됩니다.

개별 URL 부분 가져오기

URL이 구문 분석되었거나 개별 부분이 CURLU 핸들에 설정된 경우 언제든지 핸들에서 해당 부분을 다시 추출할 수 있습니다.

curl_url_get()에 대한 두 번째 인수는 추출할 부분을 지정합니다. 그것들은 모두 null로 끝나는 char * 데이터로 추출되므로 이러한 변수에 대한 포인터를 전달합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
char *host;
rc = curl_url_get(h, CURLUPART_HOST, &host, 0);

char *scheme;
rc = curl_url_get(h, CURLUPART_SCHEME, &scheme, 0);

char *user;
rc = curl_url_get(h, CURLUPART_USER, &user, 0);

char *password;
rc = curl_url_get(h, CURLUPART_PASSWORD, &password, 0);

char *port;
rc = curl_url_get(h, CURLUPART_PORT, &port, 0);

char *path;
rc = curl_url_get(h, CURLUPART_PATH, &path, 0);

char *query;
rc = curl_url_get(h, CURLUPART_QUERY, &query, 0);

char *fragment;
rc = curl_url_get(h, CURLUPART_FRAGMENT, &fragment, 0);

작업이 끝나면 반환된 문자열을 curl_free로 해제하는 것을 잊지 마십시오!

추출된 부분은 사용자가 CURLU_URLDECODE 플래그로 요청하지 않는 한 URL 디코딩되지 않습니다.

개별 URL 부분 설정

API를 사용하면 전체 URL을 구문 분석하거나 구문 분석하는 대신 CURLU 핸들에 보관된 URL의 개별 부분을 애플리케이션에서 설정할 수 있습니다.

1
2
3
4
5
6
7
8
rc = curl_url_set(urlp, CURLUPART_HOST, "www.example.com", 0);
rc = curl_url_set(urlp, CURLUPART_SCHEME, "https", 0);
rc = curl_url_set(urlp, CURLUPART_USER, "john", 0);
rc = curl_url_set(urlp, CURLUPART_PASSWORD, "doe", 0);
rc = curl_url_set(urlp, CURLUPART_PORT, "443", 0);
rc = curl_url_set(urlp, CURLUPART_PATH, "/index.html", 0);
rc = curl_url_set(urlp, CURLUPART_QUERY, "name=john", 0);
rc = curl_url_set(urlp, CURLUPART_FRAGMENT, "anchor", 0);

API는 항상 세 번째 인수에서 null로 끝나는 char * 문자열을 예상하거나 필드를 지우려면 NULL을 예상합니다. 포트 번호도 이런 식으로 문자열로 제공됩니다.

사용자가 네 번째 인수에서 CURLU_URLENCODE 플래그를 사용하여 요청하지 않는 한 설정 부분은 URL로 인코딩되지 않습니다.

쿼리에 추가

응용 프로그램은 CURLU_APPENDQUERY 플래그를 사용하여 기존 쿼리 부분의 오른쪽 끝에 문자열을 추가할 수 있습니다.

URL https://example.com/?shoes=2를 보유하는 핸들을 고려하십시오. 그러면 애플리케이션은 다음과 같이 쿼리 부분에 문자열 hat=1을 추가할 수 있습니다.

1
rc = curl_url_set(urlp, CURLUPART_QUERY, "hat=1", CURLU_APPENDQUERY);

앰퍼샌드(&) 구분 기호가 없는 경우에도 이를 삽입하므로 핸들의 전체 URL은 https://example.com/?shoes=2&hat=1과 같습니다.

추가된 문자열은 물론 추가 시 인코딩된 URL을 얻을 수도 있으며, 요청하는 경우 인코딩은 ‘=’ 문자를 건너뜁니다. 예를 들어, 우리가 이미 가지고 있는 것에 candy=M&M을 추가하고 데이터의 앰퍼샌드를 처리하기 위해 그것을 URL 인코딩합니다:

1
2
rc = curl_url_set(urlp, CURLUPART_QUERY, "candy=M&M",
CURLU_APPENDQUERY | CURLU_URLENCODE);

이제 URL은 https://example.com/?shoes=2&hat=1&candy=M%26M과 같습니다.

CURLOPT_CURLU

응용 프로그램의 편의를 위해 CURLOPT_URL의 대안으로 이미 구문 분석된 URL을 libcurl에 전달할 수 있습니다.

CURLOPT_CURLU 옵션을 사용하여 URL 문자열 대신 CURLU 핸들을 전달합니다.
예시:

1
2
3
4
5
CURLU *h = curl_url();
rc = curl_url_set(h, CURLUPART_URL, "https://example.com/", 0);

CURL *easy = curl_easy_init();
curl_easy_setopt(easy, CURLOPT_CURLU, h);
공유하기